﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using ESoft.Helpers;

namespace ESoft.Extensions {

    /// <summary>
    /// 枚举扩展
    /// </summary>
    public static partial class Extension {

        #region 获取描述,使用System.ComponentModel.Description特性设置描述

        /// <summary>
        ///     获取描述,使用System.ComponentModel.Description特性设置描述
        /// </summary>
        /// <param name="instance">枚举实例</param>
        public static string Description(this Enum instance) {
            return GetDescription(instance.GetType(), instance);
        }

        #endregion 获取描述,使用System.ComponentModel.Description特性设置描述

        #region 获取成员值

        /// <summary>
        ///     获取成员值
        /// </summary>
        /// <param name="instance">枚举实例</param>
        public static int Value(this Enum instance) {
            return GetValue(instance.GetType(), instance);
        }

        #endregion 获取成员值

        #region 获取成员值

        /// <summary>
        ///     获取成员值
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="instance">枚举实例</param>
        public static T Value<T>(this Enum instance) {
            return ConvertHelper.To<T>(Value(instance));
        }

        #endregion 获取成员值

        #region GetName(获取成员名)

        /// <summary>
        ///     获取成员名
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <param name="member">成员名、值、实例均可</param>
        private static string GetName(Type type, object member) {
            if (type == null) return string.Empty;
            if (member == null) return string.Empty;
            if (member is string) return member.ToString();
            if (type.IsEnum == false) return string.Empty;

            return Enum.GetName(type, member);
        }

        #endregion GetName(获取成员名)

        #region GetValue(获取成员值)

        /// <summary>
        ///     获取成员值
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <param name="member">成员名、值、实例均可</param>
        private static int GetValue(Type type, object member) {
            var value = member.ToStr();
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentNullException(nameof(member));

            return (int)Enum.Parse(type, member.ToString() ?? string.Empty, true);
        }

        #endregion GetValue(获取成员值)

        #region GetDescription(获取描述)

        /// <summary>
        ///     获取描述,使用System.ComponentModel.Description特性设置描述
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <param name="member">成员名、值、实例均可</param>
        private static string GetDescription(Type type, object member) {
            if (type == null)
                return string.Empty;

            var memberName = GetName(type, member);
            if (memberName.IsEmpty())
                return string.Empty;

            var field = type.GetField(memberName);
            if (field == null)
                return string.Empty;

            var attribute =
                field.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault() as DescriptionAttribute;
            if (attribute == null)
                return field.Name;

            return attribute.Description;
        }

        #endregion GetDescription(获取描述)


        /// <summary>
        /// 将枚举转为集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static IEnumerable<EnumEntity> EnumToList(this Type t) {
            if (!t.IsEnum) {
                return null;
            }
            var list = new List<EnumEntity>();

            foreach (var e in Enum.GetValues(t)) {
                EnumEntity m = new EnumEntity();
                object[] objArr = e.GetType().GetField(e.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), true);
                if (objArr != null && objArr.Length > 0) {
                    DescriptionAttribute da = objArr[0] as DescriptionAttribute;
                    m.Desction = da.Description;
                }
                m.EnumValue = Convert.ToInt32(e);
                m.EnumName = e.ToString();
                list.Add(m);
            }
            return list;
        }

        /// <summary>
        /// 枚举实体
        /// </summary>
        public class EnumEntity {
            /// <summary>  
            /// 枚举的描述  
            /// </summary>  
            public string Desction { set; get; }

            /// <summary>  
            /// 枚举名称  
            /// </summary>  
            public string EnumName { set; get; }

            /// <summary>  
            /// 枚举对象的值  
            /// </summary>  
            public int EnumValue { set; get; }
        }
    }

}